package io.itit.ecp.admin.provide.action.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.itit.ecp.admin.provide.action.req.DataRangeQueryReq;
import io.itit.ecp.admin.provide.action.req.DataRangeReq;
import io.itit.ecp.admin.provide.action.resp.DataRangeResp;
import io.itit.ecp.admin.provide.filter.IDataRangeFilter;
import io.itit.ecp.admin.provide.renderer.DataRangeRenderer;
import io.itit.ecp.admin.server.entity.DataRangeEntity;
import io.itit.ecp.admin.server.entity.DataRangeSceneEntity;
import io.itit.ecp.admin.server.service.IDataRangeSceneService;
import io.itit.ecp.admin.server.service.IDataRangeService;
import io.itit.grass.common.provide.action.req.BaseBatchIdReq;
import io.itit.grass.common.provide.action.req.BaseIdReq;
import io.itit.grass.common.provide.action.resp.ResultResp;
import io.itit.grass.common.provide.action.validation.*;
import io.itit.grass.common.server.helper.DictHelper;
import io.itit.grass.common.server.utils.ConvertUtils;
import io.itit.grass.core.common.constant.GrassCoreConstant;
import io.itit.grass.core.server.exception.GrassCoreException;
import io.itit.grass.estelle.starter.core.ExcelXSSFUtil;
import io.itit.grass.estelle.starter.parse.ExcelParseManage;
import io.itit.grass.estelle.starter.util.JsonUtil;
import io.itit.grass.web.wall.utils.PageUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * @Author：Roy
 * @Description：数据范围控制类
 * @Date：Create by 2024-01-17 16:55:06
 */
@Api(tags = "数据角色")
@RestController
@RequestMapping("/ecp-admin/dataRange")
public class DataRangeController {

    @Resource
    private IDataRangeService dataRangeService;

    @Resource
    private IDataRangeSceneService dataRangeSceneService;

    @ApiOperation("分页查询")
    @PostMapping("queryPage")
    @RequiresPermissions("ecp-admin:dataRange:search")
    public ResultResp<IPage<DataRangeResp>> queryPage(@RequestBody @Validated(IQueryPage.class) DataRangeQueryReq req) {
        Page<DataRangeEntity> page = dataRangeService.page(PageUtils.getPage(req, DataRangeEntity.class), buildQW(req));
        return ResultResp.success(ConvertUtils.convert(page, DataRangeResp.class));
    }

    @ApiOperation("查询全部")
    @PostMapping("queryList")
    @RequiresPermissions(value = {"ecp-admin:dataRange:search", "grass-core:user:allotDataRangeRole"}, logical = Logical.OR)
    public ResultResp<List<DataRangeResp>> queryList(@RequestBody @Validated(IQuery.class) DataRangeQueryReq req) {
        List<DataRangeEntity> list = dataRangeService.list(buildQW(req));
        return ResultResp.success(ConvertUtils.convert(list, DataRangeResp.class));
    }

    @ApiOperation("详情")
    @PostMapping("detail")
    // 查询详情和分配数据范围权限预览共享接口权限
    @RequiresPermissions(value = {"ecp-admin:dataRange:search", "grass-core:user:allotDataRangeRole"}, logical = Logical.OR)
    public ResultResp<DataRangeResp> detail(@RequestBody @Validated(IRequired.class) BaseIdReq req) {
        DataRangeResp dataRangeResp = ConvertUtils.copy(dataRangeService.getById(req.getId()), DataRangeResp.class);
        dataRangeResp.setSceneIdList(dataRangeSceneService.lambdaQuery()
                .eq(DataRangeSceneEntity::getDataRangeId, dataRangeResp.getId())
                .list()
                .stream()
                .map(DataRangeSceneEntity::getSceneId)
                .collect(Collectors.toList()));
        return ResultResp.success(dataRangeResp);
    }

    /**
     * 组装查询条件
     *
     * @param req
     * @return
     */
    private static LambdaQueryWrapper<DataRangeEntity> buildQW(DataRangeQueryReq req) {
        return Wrappers.<DataRangeEntity>lambdaQuery()
                .eq(StringUtils.isNotEmpty(req.getRangeCode()), DataRangeEntity::getRangeCode, req.getRangeCode())
                .eq(StringUtils.isNotEmpty(req.getRangeName()), DataRangeEntity::getRangeName, req.getRangeName())
                .eq(StringUtils.isNotEmpty(req.getRangeLevel()), DataRangeEntity::getRangeLevel, req.getRangeLevel())
                .in(CollectionUtils.isNotEmpty(req.getRangeLevelList()), DataRangeEntity::getRangeLevel, req.getRangeLevelList())
                .eq(StringUtils.isNotEmpty(req.getRemark()), DataRangeEntity::getRemark, req.getRemark())
                .eq(req.getStatus() != null, DataRangeEntity::getStatus, req.getStatus())
                .in(CollectionUtils.isNotEmpty(req.getStatusList()), DataRangeEntity::getStatus, req.getStatusList())
                .eq(StringUtils.isNotEmpty(req.getDeptId()), DataRangeEntity::getDeptId, req.getDeptId())
                .in(CollectionUtils.isNotEmpty(req.getIds()), DataRangeEntity::getId, req.getIds())
                .last(StringUtils.isNotEmpty(req.getSortColumn()), PageUtils.lastOrderBy(req))
                .orderByDesc(StringUtils.isEmpty(req.getSortColumn()), DataRangeEntity::getCreateTm);
    }

    @ApiOperation("新增")
    @PostMapping("add")
    @RequiresPermissions("ecp-admin:dataRange:add")
    public ResultResp<Boolean> add(@RequestBody @Validated({IAdd.class}) DataRangeReq req) {
        long cnt = dataRangeService.lambdaQuery().eq(DataRangeEntity::getRangeCode, req.getRangeCode()).count();
        GrassCoreException.throwEx(cnt > 0, GrassCoreConstant.ROLE_CODE_EXISTS);
        return ResultResp.success(dataRangeService.save(ConvertUtils.convertIgnoreId(req, DataRangeEntity.class), req.getSceneIdList()));
    }

    @ApiOperation("编辑")
    @PostMapping("update")
    @RequiresPermissions("ecp-admin:dataRange:update")
    public ResultResp<Boolean> update(@RequestBody @Validated({IUpdate.class}) DataRangeReq req) {
        return ResultResp.success(dataRangeService.update(ConvertUtils.copy(req, DataRangeEntity.class), req.getSceneIdList()));
    }

    @ApiOperation("启用/禁用")
    @PostMapping("enableOrDisable")
    @RequiresPermissions("ecp-admin:dataRange:enableOrDisable")
    public ResultResp<Boolean> enableOrDisable(@RequestBody @Validated({IEnable.class}) DataRangeReq req) {
        DictHelper.i().checkV(IDataRangeFilter.DATA_RANGE_STATUS, req.getStatus());
        return ResultResp.success(dataRangeService.update(Wrappers.<DataRangeEntity>lambdaUpdate()
                .set(DataRangeEntity::getStatus, req.getStatus())
                .eq(DataRangeEntity::getId, req.getId())));
    }

    @ApiOperation("删除(根据Id删)")
    @PostMapping("deleteById")
    @RequiresPermissions("ecp-admin:dataRange:deleteById")
    public ResultResp<Boolean> deleteById(@RequestBody @Validated({IRequired.class}) BaseIdReq req) {
        return ResultResp.success(dataRangeService.removeById(req.getId()));
    }

    @ApiOperation("批量删除")
    @PostMapping("batchDelete")
    @RequiresPermissions("ecp-admin:dataRange:batchDelete")
    public ResultResp<Boolean> batchDelete(@RequestBody @Validated({IRequired.class}) BaseBatchIdReq req) {
        return ResultResp.success(dataRangeService.removeBatchByIds(req.getIds(), 1000));
    }

    @ApiOperation("导入")
    @PostMapping("upload")
    @RequiresPermissions("ecp-admin:dataRange:upload")
    public ResultResp<Integer> upload(@RequestParam("file") MultipartFile file, Boolean ignoreError) {
        return ResultResp.success(ExcelParseManage.i().process(DataRangeRenderer.ENTITY_NAME, file, ignoreError));
    }

    @ApiOperation("导出")
    @PostMapping("export")
    @RequiresPermissions("ecp-admin:dataRange:export")
    public void export(@RequestBody @Validated(IExport.class) DataRangeQueryReq req, HttpServletResponse response) {
        ExcelXSSFUtil.export("DataRangeExport", JsonUtil.toJson(dataRangeService.list(buildQW(req)), new IDataRangeFilter.DataRangeExportFilter()), response);
    }
}